/**
 * @file
 * @brief This file implements a "very" simple sample client.
 * 
 * The client connects to the server, running at SERVERHOST:SERVERPORT
 * and performs a number of storage_* operations. If there are errors,
 * the client exists.
 */

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "storage.h"
#include "utils.h"

#define SERVERHOST "localhost"
#define SERVERPORT 1111
#define SERVERUSERNAME "admin"
#define SERVERPASSWORD "dog4sale"
#define TABLE "marks"
#define KEY "ece297"

#define HOST_NAME_LEN 20
#define USER_NAME_LEN 20
#define PASSWORD_LEN 20
#define TABLE_LEN 20
#define KEY_LEN 20
#define LOGGING 2


void print_promt();
void* exec_connect();
int exec_authenticate(void *);
void exec_get(void **conn,struct storage_record *r );
void exec_set(void **conn, struct storage_record *r);
void exec_disconnect(void **conn);
FILE* create_file();

FILE* logfile = NULL;
/**
 * @brief Start a client to interact with the storage server.
 *
 * If connect is successful, the client performs a storage_set/get() on
 * TABLE and KEY and outputs the results on stdout. Finally, it exists
 * after disconnecting from the server.
 */
int main(int argc, char *argv[]) {
	if(LOGGING != 0){
		if(LOGGING == 1) logfile = stdout;
		else if(LOGGING == 2) logfile = create_file();
	}
	int authenrized = 0;
	int stop = 0;
	void* connection = NULL;
	struct storage_record record;
	strncpy(record.value, "some_value", sizeof record.value);

	while(1){
		if(stop == 1) break;
		int command_num;
		print_promt();
		if(scanf("%d",&command_num) != 0){
			switch(command_num){
			case 1:
				connection = exec_connect();
				break;
			case 2:
				authenrized = exec_authenticate(connection);
				break;
			case 3:
			    exec_get(&connection,&record );
				break;
			case 4:
				exec_set(&connection,&record);
				break;
			case 5:
				exec_disconnect(&connection);
				break;
			case 6:
				if(connection != NULL) exec_disconnect(&connection);
				stop = 1;
				break;
			default:
				printf("Unknown Command\n\t");
				break;
			}
		}
		else {
			printf("Invalid Input\n\t");
		}
	}
	return 0;
	/*
  // Connect to server
  void *conn = storage_connect(SERVERHOST, SERVERPORT);
  if(!conn) {
    printf("Cannot connect to server @ %s:%d. Error code: %d.\n",
           SERVERHOST, SERVERPORT, errno);
    return -1;
  }

  // Authenticate the client.
  int status = storage_auth(SERVERUSERNAME, SERVERPASSWORD, conn);
  if(status != 0) {
    printf("storage_auth failed with username '%s' and password '%s'. " \
           "Error code: %d.\n", SERVERUSERNAME, SERVERPASSWORD, errno);
    storage_disconnect(conn);
    return status;
  }
  printf("storage_auth: successful.\n");

  // Issue storage_set
  struct storage_record r;
  strncpy(r.value, "some_value", sizeof r.value);
  status = storage_set(TABLE, KEY, &r, conn);
  if(status != 0) {
    printf("storage_set failed. Error code: %d.\n", errno);
    storage_disconnect(conn);
    return status;
  }
  printf("storage_set: successful.\n");

  // Issue storage_get
  status = storage_get(TABLE, KEY, &r, conn);
  if(status != 0) {
    printf("storage_get failed. Error code: %d.\n", errno);
    storage_disconnect(conn);
    return status;
  }
  printf("storage_get: the value returned for key '%s' is '%s'.\n",
         KEY, r.value);

  // Disconnect from server
  status = storage_disconnect(conn);
  if(status != 0) {
    printf("storage_disconnect failed. Error code: %d.\n", errno);
    return status;
  }

  // Exit
  return 0;
  */
}

void print_promt(){
	printf(	" ---------------------\n"
		" 1) Connect\n"
 		" 2) Authenticate\n"
		" 3) Get\n"
		" 4) Set\n"
		" 5) Disconnect\n"
		" 6) Exit\n"
		" ---------------------\n"
		"Please enter your selection: ");
}

void* exec_connect(){
	char hostname[HOST_NAME_LEN];
	int port;
	void *conn = NULL;

	printf("Please input the hostname: ");
	scanf("%s",hostname);
	printf("Please input the port: ");
	scanf("%d", &port);

	conn = storage_connect(hostname, port);
	if(!conn) {
	    printf("Cannot connect to server @ %s:%d. Error code: %d.\n",
	    		hostname, port, errno);
	    return NULL;
	}
	else {
		printf("Connection established.\n");
		return conn;
	}
}

int exec_authenticate(void * conn){

	if(conn == NULL) {
		printf("No connection yet\n");
		return 0;
	}
	char username[USER_NAME_LEN];
	char password[PASSWORD_LEN];

	printf("Please input the username: ");
	if(!scanf("%s",username)){
		printf("Wrong input\n");
		return 0;
	}
	printf("Please input the password: ");
	if(!scanf("%s",password)){
		printf("No Password\n");
		return 0;
	}
	if(storage_auth(username,password,conn) == 0){
		printf("User identity verification successed\n");
		return 1;
	}
	else {
		printf("Authentication failed\n");
		return 0;
	}
}

void exec_get(void **conn,struct storage_record *r ){
	char table_str[TABLE_LEN];
	char key_str[KEY_LEN];
	printf("Please input the Table: ");
	if(!scanf("%s",table_str)){
		printf("table name is not correct/n");
		return;
	}
	printf("Please input the key: ");
	if(!scanf("%s",key_str)){
		printf("key is not valid/n");
		return;
	}
	if(storage_get(table_str, key_str, r, *conn)!= 0){
		printf("storage_get failed. Error code: %d.\n", errno);
		storage_disconnect(*conn);
		return;
	}
	printf("storage_get: the value returned for key '%s' is '%s'.\n",
	         KEY, (*r).value);

}
void exec_set(void **conn, struct storage_record *r){
	char table_str[TABLE_LEN];
	char key_str[KEY_LEN];
	printf("Please input the Table: ");
	if(!scanf("%s",table_str)){
		printf("table name is not correct/n");
		return;
	}
	printf("Please input the key: ");
	if(!scanf("%s",key_str)){
		printf("key is not valid/n");
		return;
	}

	if(storage_set(table_str, key_str, r, *conn) != 0){

		printf("storage_set failed. Error code: %d.\n", errno);
		storage_disconnect(*conn);
		return;
	}
	printf("storage_set: successful.\n");
}
void exec_disconnect(void **conn){
	if(storage_disconnect(*conn)!= 0)printf("storage_disconnect failed. Error code: %d.\n", errno);
	*conn = NULL;
	printf("storage_disconnect succssed\n");
	return;
}
FILE* create_file(){
	char time[40];
	char file_name[40];
	get_timeinfo(time);
	sprintf(file_name,"client-%s.log",time);
	FILE* _log_file = fopen(file_name,"w");
	return _log_file;
}
